home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Xconq 7.1.0 / src / xconq-7.1.0 / x11 / ximf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  10.3 KB  |  412 lines  |  [TEXT/R*ch]

  1. /* X11-specific functions for image families in Xconq.
  2.    Copyright (C) 1992, 1993, 1994, 1995 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. #include "config.h"
  10. #include "misc.h"
  11. #include "lisp.h"
  12. #include "module.h"
  13. #include "system.h"
  14. #include "imf.h"
  15. extern int smallest_image PARAMS ((ImageFamily *imf, int *wp, int *hp));
  16.  
  17. #include <X11/Xos.h>
  18. #include <X11/Xlib.h>
  19. #include <X11/Xutil.h>
  20. #include <X11/Xresource.h>
  21.  
  22. #include "ximf.h"
  23.  
  24. extern char *imflib;
  25.  
  26. static Pixmap x11_load_bitmap PARAMS ((Display *dpy, Window rootwin,
  27.                       char *name, char *ext, int *w, int *h));
  28. static void x11_make_color_pixmap PARAMS ((Display *dpy, Window rootwin,
  29.                       Image *img));
  30.  
  31. X11Image *
  32. init_x11_image(img)
  33. Image *img;
  34. {
  35.     X11Image *ximg;
  36.  
  37.     ximg = (X11Image *) xmalloc(sizeof(X11Image));
  38.     ximg->mono = None;
  39.     ximg->mask = None;
  40.     /* Point to the generic image. */
  41.     ximg->generic = img;
  42.     ximg->colpix = NULL;
  43.     return ximg;
  44. }
  45.  
  46. X11Image *
  47. get_x11_image(img)
  48. Image *img;
  49. {
  50.     X11Image *ximg;
  51.  
  52.     if (img->hook)
  53.       return (X11Image *) img->hook;
  54.     ximg = init_x11_image(img);
  55.     img->hook = (char *) ximg;
  56.     return ximg;
  57. }
  58.  
  59. /* This tries to fill in the given image family by looking for and loading
  60.    standard X11 bitmap files. */
  61.  
  62. void
  63. x11_load_imf(dpy, rootwin, imf)
  64. Display *dpy;
  65. Window rootwin;
  66. ImageFamily *imf;
  67. {
  68.     int w, h;
  69.     Pixmap pic;
  70.     Image *img;
  71.     X11Image *ximg;
  72.  
  73.     /* If no imf or no name, don't even try. */
  74.     if (imf == NULL || imf->name == NULL)
  75.       return;
  76.     if (strcmp(imf->name, "none") == 0)
  77.       return;
  78.     if (0 /* found an imf file */) {
  79.     } else {
  80.     img = NULL;
  81.     ximg = NULL;
  82.     /* Just grab up plausibly-named bitmaps. */
  83.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "b", &w, &h);
  84.     if (pic != None) {
  85.         img = get_img(imf, w, h);
  86.         ximg = get_x11_image(img);
  87.         ximg->mono = pic;
  88.     }
  89.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "m", &w, &h);
  90.     if (pic != None) {
  91.         img = get_img(imf, w, h);
  92.         ximg = get_x11_image(img);
  93.         ximg->mask = pic;
  94.     }
  95.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "8.b", &w, &h);
  96.     if (pic != None) {
  97.         img = get_img(imf, w, h);
  98.         ximg = get_x11_image(img);
  99.         ximg->mono = pic;
  100.     }
  101.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "8.m", &w, &h);
  102.     if (pic != None) {
  103.         img = get_img(imf, w, h);
  104.         ximg = get_x11_image(img);
  105.         ximg->mask = pic;
  106.     }
  107.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "32.b", &w, &h);
  108.     if (pic != None) {
  109.         img = get_img(imf, w, h);
  110.         ximg = get_x11_image(img);
  111.         ximg->mono = pic;
  112.     }
  113.     pic = x11_load_bitmap(dpy, rootwin, imf->name, "32.m", &w, &h);
  114.     if (pic != None) {
  115.         img = get_img(imf, w, h);
  116.         ximg = get_x11_image(img);
  117.         ximg->mask = pic;
  118.     }
  119. #if 0
  120.     if (imf->numsizes == 0) {
  121.         /* (should not complain unless no colors either -
  122.            check mac rules) */
  123.         fprintf(stderr,
  124.             "Image named \"%s\" not found here or in \"%s\"!\n",
  125.             imf->name, imflib);
  126.     }
  127. #endif
  128.     if (img && ximg)
  129.       img->hook = (char *) ximg;
  130.     }
  131. }
  132.  
  133. /* Try to load a bitmap of the given name, looking in both the current dir
  134.    and the library dir.  Warns about failure, but returns None, so the rest
  135.    of the code will continue to function. */
  136.  
  137. static Pixmap
  138. x11_load_bitmap(dpy, rootwin, name, ext, wp, hp)
  139. Display *dpy;
  140. Window rootwin;
  141. char *name, *ext;
  142. int *wp, *hp;
  143. {
  144.     int hotx, hoty;
  145.     unsigned int w, h;
  146.     Pixmap rslt;
  147.     static char sbuf[1000];
  148.  
  149.     if (ext != NULL) {
  150.     make_pathname(NULL, name, ext, sbuf);
  151.     if (XReadBitmapFile(dpy, rootwin, sbuf,
  152.                 &w, &h, &rslt, &hotx, &hoty) == BitmapSuccess) {
  153.         DGprintf("Loaded bitmap \"%s\"\n", sbuf);
  154.         *wp = w;  *hp = h;
  155.         return rslt;
  156.     }
  157.     make_pathname(imflib, name, ext, sbuf);
  158.     if (XReadBitmapFile(dpy, rootwin, sbuf,
  159.                 &w, &h, &rslt, &hotx, &hoty) == BitmapSuccess) {
  160.         DGprintf("Loaded bitmap \"%s\"\n", sbuf);
  161.         *wp = w;  *hp = h;
  162.         return rslt;
  163.     }
  164.     }
  165.     return None;
  166. }
  167.  
  168. /* if (force): prefer data over rawdata; always re-create pixmaps */
  169.  
  170. void
  171. x11_interp_imf(dpy, rootwin, imf, force)
  172. Display *dpy;
  173. Window rootwin;
  174. ImageFamily *imf;
  175. int force;
  176. {
  177.     int w, h, rowbytes, numbytes;
  178.     Image *img;
  179.     X11Image *ximg;
  180.  
  181.     for (img = imf->images; img != NULL; img = img->next) {
  182.     w = img->w;  h = img->h;
  183.     ximg = get_x11_image(img);
  184.     if (img->monodata != lispnil && (img->rawmonodata == NULL || force)) {
  185.         rowbytes = (w + 7) / 8;
  186.         numbytes = h * rowbytes;
  187.         img->rawmonodata = xmalloc(numbytes);
  188.         interp_bytes(img->monodata, numbytes, img->rawmonodata, 0);
  189.         reverse_bit_endianness(img->rawmonodata, numbytes);
  190.     }
  191.     if (img->rawmonodata && (ximg->mono == None || force)) {
  192.         ximg->mono =
  193.           XCreateBitmapFromData(dpy, rootwin, img->rawmonodata, w, h);
  194.     }
  195.     if (img->maskdata != lispnil && (img->rawmaskdata == NULL || force)) {
  196.         rowbytes = (w + 7) / 8;
  197.         numbytes = h * rowbytes;
  198.         img->rawmaskdata = xmalloc(numbytes);
  199.         interp_bytes(img->maskdata, numbytes, img->rawmaskdata, 0);
  200.         reverse_bit_endianness(img->rawmaskdata, numbytes);
  201.     }
  202.     if (img->rawmaskdata && (ximg->mask == None || force)) {
  203.         ximg->mask =
  204.           XCreateBitmapFromData(dpy, rootwin, img->rawmaskdata, w, h);
  205.     }
  206.     if (img->colrdata != lispnil && (img->rawcolrdata == NULL || force)) {
  207.         rowbytes = (w * img->pixelsize + 7) / 8;
  208.         numbytes = h * rowbytes;
  209.         img->rawcolrdata = xmalloc(numbytes);
  210.         interp_bytes(img->colrdata, numbytes, img->rawcolrdata, 0);
  211.     }
  212.     if (img->rawcolrdata && (ximg->colr == None || force)) {
  213.         x11_make_color_pixmap(dpy, rootwin, img);
  214.     }
  215.     }
  216. }
  217.  
  218. /* X11 bitmaps are always in little-endian bit order, while IMF images
  219.    are always big-endian in bit order, so we must reverse the bits
  220.    in each byte individually. */
  221.  
  222. void
  223. reverse_bit_endianness(rawdata, numbytes)
  224. char *rawdata;
  225. int numbytes;
  226. {
  227.     int i, j, byte, byte2;
  228.  
  229.     for (i = 0; i < numbytes; ++i) {
  230.     byte = rawdata[i];
  231.     byte2 = 0;
  232.     for (j = 0; j < 8; ++j) {
  233.         byte2 = (byte2 << 1) | (byte & 1);
  234.         byte >>= 1;
  235.     }
  236.     rawdata[i] = byte2;
  237.     }
  238. }
  239.  
  240. static void
  241. x11_make_color_pixmap(dpy, rootwin, img)
  242. Display *dpy;
  243. Window rootwin;
  244. Image *img;
  245. {
  246.     unsigned short ipal[4][256];
  247.     Pixel idx[256], pixel;
  248.     int r, ri, rc, depth, c, ln, screen, rsize;
  249.     int rowbytesize, bytesize, rmask;
  250.     XColor col;
  251.     char buf[BUFSIZE], *dp, *rp, *data;
  252.     Obj *pal, *color;
  253.     Colormap cmap;
  254.     Pixmap pixmap;
  255.     XImage *ximage;
  256.     GC gc;
  257.     X11Image *ximg = (X11Image *) img->hook;
  258.  
  259.     if (ximg == NULL || img->rawcolrdata == NULL)
  260.       return;
  261.     /* Can't make color pixmaps if we don't have any colors. */
  262.     if (img->palette == lispnil && img->rawpalette == NULL)
  263.       return;
  264.  
  265.     if (!img->rawpalette) {
  266.     /* Parse the palette. */
  267.     c = 0;
  268.     for (pal = img->palette; pal != lispnil; pal = cdr(pal)) {
  269.         color = car(pal);
  270.         ipal[0][c] = c_number(car(color));
  271.         ipal[1][c] = c_number(car(cdr(color)));
  272.         ipal[2][c] = c_number(car(cdr(cdr(color))));
  273.         ipal[3][c] = c_number(car(cdr(cdr(cdr(color)))));
  274.         c++;
  275.     }
  276.     img->numcolors = c;
  277.     if (c == 0)
  278.       return;
  279.   
  280.     /* store palette */
  281.     img->rawpalette = (int *) xmalloc(img->numcolors * 4 * sizeof(int));
  282.     for (c = 0; c < img->numcolors; c++) {
  283.         for (ln = 0; ln < 4; ln++) {
  284.         img->rawpalette[4 * c + ln] = ipal[ln][c];
  285.         }
  286.     }
  287.     }
  288.  
  289.     screen = DefaultScreen(dpy);
  290.     cmap = XDefaultColormap(dpy, screen);
  291.     depth = DefaultDepth(dpy, screen);
  292.     if (depth % 8)
  293.       return;
  294.  
  295.     if (img->numcolors <= 0) {
  296.     run_warning("No colors?");
  297.     return;
  298.     }
  299.  
  300.     /* allocate colors */
  301.     ximg->colpix = (Pixel *) xmalloc(img->numcolors * sizeof(Pixel));
  302.     for (c = 0; c < img->numcolors; c++) {
  303.     col.red   = img->rawpalette[4 * c + 1];
  304.     col.green = img->rawpalette[4 * c + 2];
  305.     col.blue  = img->rawpalette[4 * c + 3];
  306.     col.flags = DoRed | DoGreen | DoBlue;
  307.     if (XAllocColor(dpy, cmap, &col)) {
  308.         ximg->colpix[c] = col.pixel;
  309.     } else {
  310.         sprintf(buf, "%2.2x%2.2x%2.2x",
  311.             img->rawpalette[4*c+1],
  312.             img->rawpalette[4*c+2],
  313.             img->rawpalette[4*c+3]);
  314.         init_warning("Cannot alloc color #%s, will leave black", buf);
  315.         ximg->colpix[c] = XBlackPixel(dpy,screen);
  316.     }
  317.     }
  318.  
  319.     /* find reverse index->pixel mapping */
  320.     for (c = 0; c < 256; c++) {
  321.     idx[c] = XBlackPixel(dpy, screen);
  322.     }
  323.     for (c = 0; c < img->numcolors; c++) {
  324.     idx[img->rawpalette[4 * c + 0]] = ximg->colpix[c];
  325.     }
  326.  
  327.     /* make color data */
  328.     rsize = img->pixelsize;
  329.     rmask = (1 << img->pixelsize) - 1;
  330.     rowbytesize = img->w * depth / 8;
  331.     bytesize = rowbytesize * img->h;
  332.     data = xmalloc(bytesize * sizeof(char));
  333.     dp = data;
  334.     rp = img->rawcolrdata;
  335.     for (r = 0; r < img->h; r++) {
  336.     ri = 8 - img->pixelsize;
  337.     for (c = 0; c < img->w; c++) {
  338.         rc = ((int) (*rp >> ri)) & rmask;
  339.         if (ri) {
  340.         ri -= img->pixelsize;
  341.         } else {
  342.         ri = 8 - img->pixelsize;
  343.         rp++;
  344.         }
  345.         pixel = idx[rc];
  346.         for (ln = depth - 8; ln >= 0; ln -= 8) {
  347.         *dp = (pixel >> ln) & 0xff;
  348.         dp++;
  349.         }
  350.     }
  351.     if ((img->pixelsize * img->w) % 8) {
  352.         rp++;
  353.     }
  354.     }
  355.  
  356.     /* convert to XImage */
  357.     ximage = XCreateImage(dpy, DefaultVisual(dpy, screen), depth,
  358.               ZPixmap, 0, data, img->w, img->h,
  359.               8, rowbytesize);
  360.     if (!ximage) {
  361.     free(data);
  362.     return;
  363.     }
  364.     ximage->byte_order = MSBFirst;
  365.     ximage->bitmap_bit_order = MSBFirst;
  366.     
  367.     /* and finally to Pixmap */
  368.     pixmap = XCreatePixmap(dpy, rootwin, img->w, img->h, depth);
  369.     if (!pixmap)
  370.       pixmap = None;
  371.     if (pixmap == None) {
  372.     XDestroyImage(ximage);
  373.     /* XDestroyImage also frees data */
  374.     return;
  375.     }
  376.     gc = XCreateGC(dpy, pixmap, 0, NULL);
  377.     XPutImage(dpy, pixmap, gc, ximage, 0, 0, 0, 0,
  378.           ximage->width, ximage->height);
  379.     XFreeGC(dpy, gc);
  380.     XDestroyImage(ximage);
  381.     /* XDestroyImage also frees data */
  382.  
  383.     ximg->colr = pixmap;
  384. }
  385.  
  386. /* (should be a generic routine) */
  387. int
  388. smallest_image(imf, wp, hp)
  389. ImageFamily *imf;
  390. int *wp, *hp;
  391. {
  392.     Image *img, *smallest = NULL;
  393.  
  394.     if (imf == NULL)
  395.       return FALSE;
  396.     for (img = imf->images; img != NULL; img = img->next) {
  397.     if (smallest == NULL || (img->w < smallest->w && img->h < smallest->h))
  398.       smallest = img;
  399.     }
  400.     if (smallest != NULL) {
  401.     *wp = smallest->w;  *hp = smallest->h;
  402.     return TRUE;
  403.     }
  404.     return FALSE;
  405. }
  406.  
  407. void
  408. make_generic_image_data(imf)
  409. ImageFamily *imf;
  410. {
  411. }
  412.